package com.cap.bts.crmdp.dealer.masterinfo.dao.impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.engine.SessionFactoryImplementor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.cap.bts.crmdp.dealer.masterinfo.dao.IServiceInfoDefDao;
import com.cap.bts.crmdp.dealer.masterinfo.domain.ServiceInfoDefModel;
import com.cap.bts.framework.common.dao.callback.NativeQueryJpaCallback;
import com.cap.bts.framework.common.dao.impl.BaseDaoImpl;
import com.cap.bts.framework.common.exception.AppException;

@Repository("iServiceInfoDefDao")
public class ServiceInfoDefDaoImpl extends BaseDaoImpl<ServiceInfoDefModel, Long> implements
                                                                                 IServiceInfoDefDao {
//	private static final Logger LOGGER = Logger.getLogger(ServiceInfoDefDaoImpl.class);
    @Inject
    public ServiceInfoDefDaoImpl(@Value("com.cap.bts.crmdp.dealer.masterinfo.domain.ServiceInfoDefModel") Class<ServiceInfoDefModel> clazz) {
        super(clazz);

    }

    @Override
    public ServiceInfoDefModel insertServiceInfo(ServiceInfoDefModel serviceInfoDefModel)
                                                                                         throws AppException {
        return save(serviceInfoDefModel);

    }

    @Override
    public void removeServiceInfoDef(ServiceInfoDefModel serviceInfoDefModel) throws AppException {
        remove(serviceInfoDefModel);
    }

    @Override
    public List<ServiceInfoDefModel> getAllServiceInfoDef() throws AppException {
        String selectStr = "select * from tm_service_def a";
        // 查询结果集的SQL
        StringBuilder selectSql = new StringBuilder();

        StringBuilder where = new StringBuilder();
        where.append(" where 1=1 ");

        selectSql.append(selectStr).append(where.toString());

        return super.getJpaTemplate().execute(
            new NativeQueryJpaCallback<ServiceInfoDefModel>(selectSql.toString(),
                ServiceInfoDefModel.class));
    }

    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2015年10月27日
     * @see com.cap.bts.crmdp.dealer.masterinfo.dao.IServiceInfoDefDao#getViewForService(java.lang.String)
    **/
    @Override
    public List<ServiceInfoDefModel> getViewForService(String sql) throws AppException {
        return this.getListByNativeQuery(sql);
    }

    /**
     * 根据服务代码查询信息
     * @see com.cap.bts.crmdp.dealer.masterinfo.dao.IServiceInfoDefDao#getServiceInfoDefList(java.lang.String)
     */
    @Override
    public List<ServiceInfoDefModel> getServiceInfoDefList(String code) throws AppException {
        String sqlString = "select * from tm_service_def where code=?1";
        return super.getListByNativeQueryWithVaParam(sqlString, code);
    }

    @Override
    public boolean updateServiceInfoDefinfo(ServiceInfoDefModel serviceInfoDefModel, Long id)
                                                                                             throws AppException {
        ServiceInfoDefModel serviceInfoDefModel2 = findById(id);
        serviceInfoDefModel2.setCode(serviceInfoDefModel.getCode());
        serviceInfoDefModel2.setName(serviceInfoDefModel.getName());
        update(serviceInfoDefModel2);
        
        return true;
        	
    }

	@Override
	public void weCareDataSynchronizationStoredProcedure() throws AppException {
		super.getEntityManager().createNativeQuery("{call prc_item_master_update()}").executeUpdate();
	}

	
	@Override
    public void batchInsert(List<ServiceInfoDefModel> productDataList) throws AppException{
    	Session session = (org.hibernate.Session) getEntityManager().getDelegate();
		SessionFactoryImplementor sf = (SessionFactoryImplementor) session.getSessionFactory();
		Connection connection = null;
		PreparedStatement pstmt = null;
		PreparedStatement pstmtDel = null;
		String batchId = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + "_" + ((int) (Math.random() * (99999 - 10000 + 1)) + 10000);
		try{
			connection = sf.getConnectionProvider().getConnection();
			connection.setAutoCommit(false);
			
			String sql ="INSERT INTO tm_service_def (  " +
					"   CODE ,  " +
					"   NAME ,  " +
					"   CREATE_BY ,  " +
					"   CREATE_DATE ,  " +
					"   LAST_UPDATE_BY ,  " +
					"   LAST_UPDATE_DATE,  " +
					"  BATCH_ID  " +
					")  " +
					"VALUES  " +
					"  (  " +
					"    ?,  " +
					"    ?,  " +
					"    ?,  " +
					"    ?,  " +
					"    ?,  " +
					"    ?,  " +
					"    ?  " +
					"  )";
			
			pstmt = connection.prepareStatement(sql);
			
			Timestamp time = new Timestamp(new Date().getTime());
			int i = 0;
			for (ServiceInfoDefModel dto : productDataList) {
				i++;
				
				pstmt.setString(1, dto.getCode());
				pstmt.setString(2, dto.getName());
				pstmt.setInt(3, 0);
				pstmt.setTimestamp(4, time);
				pstmt.setInt(5, 0);
				pstmt.setTimestamp(6, time);
				pstmt.setString(7, batchId);
				
				pstmt.addBatch();
				
				if(i%30000 == 0){
					pstmt.executeBatch();     
					connection.commit();     
					pstmt.clearBatch(); 
				}
				
			}
			
			if(i%30000 != 0){
				pstmt.executeBatch();     
				connection.commit();     
			}
			
			
			String delSql = "delete from tm_service_def where BATCH_ID <> ?  or BATCH_ID is null";
			
			pstmtDel =  connection.prepareStatement(delSql);
			pstmtDel.setString(1, batchId);
			pstmtDel.executeUpdate();
			
			
			String initSql = "{call prc_item_master_update()}";
			
			CallableStatement callableStatement = connection.prepareCall(initSql);
			callableStatement.executeUpdate();
			callableStatement.close();
			
			connection.commit();
			
		}catch(Exception e){
			try {
				connection.rollback();
			} catch (SQLException e1) {
				logger.error("", e1);
			}
			throw new AppException("ERROR", e);
		}finally{
			try {
				if(connection != null){
					connection.setAutoCommit(true);
					pstmt.close();
					if(pstmtDel != null){
						pstmtDel.close();
					}
					connection.close();
				}
			} catch (SQLException e) {
				logger.error("", e);
				pstmt = null;
				pstmtDel = null;
				connection = null;
			}
		}
    	
    	
    	
    }
}
